This tool in this directory, mpkg, is a system-level package manager.
It is meant to deploy and remove pre-built packages in PAC format.
See ../mpac for general information on the format itself.

Note that due to some design decisions behind this tool, its scope is
quite different from what is generally associated with a system package
manager. Compared to Arch pacman or Void xbps, mpkg fills the role of tar
when tar used by either pacman or xbps. In particular, it does not handle
package metadata, and does not fetch packages.

mpkg basically implements undoable `tar -x` with some extra quirks
to simplify common usage cases (search paths for package files etc).


Design and usage notes
~~~~~~~~~~~~~~~~~~~~~~
mpkg is designed with the assumption that the unit of consistency is a
repository, not a package, and that package metadata (descriptions,
dependency tree and so on) belongs to the repository as a whole instead
of being attached to individual packages. Consequently, PAC format has no
provisions for storing metadata within the package files.

The idea is to have another, distro-specific tool that would fetch packages,
including dependencies if appropriate, and then either run mpkg, or let the
user run mpkg.

The intended procedure is that the higher-level tool downloads and parses
repository index, figures out which packages it needs, downloads the packages,
and then uses mpkg to deploy them. This way, mpkg always works with a single
pac file and the higher-level tool handles inter-pac relations.

Another consequence of this assumption is very limited conflict checks that
mpkg performs, reporting only the names of the conflicting files but not the
packages they come from. The repository should be consistent and therefore no
two packages from the repository should be in conflict. If there are mutually
exclusive alternatives, those too should be marked in repository index and
not handled by mpkg. Cross-repository conflicts should be excluded using
package groups and different installation prefixes.

Whenever a single project provides several components that may be installed
independently, the project should be a repository and each component should
be a package. In general, packages should be split so that each is either
installed whole or not installed at all.

mpkg provides a way to silently skip directories from (a group of) packages
during installation. This feature was included primarily as a way of dealing
with locales and language-specific man pages, when multiple languages are
included with the package but the user may only want to install one or two
of those. It should be used as a last resort measure however; whenever
possible, optional language support should come in separate pacs, especially
when natural language support is provided externally to the project (i.e. not
by the same people who write the code), which is often the case.


Package groups
~~~~~~~~~~~~~~
Groups are intended to be used mostly for packages sharing common path prefix
of some sort. The idea is to keep namespaces separate when packages clearly
cannot be in conflict, and also to get rid of the common prefix in every
single .pac file.

Planned use cases:

  * linux-firmware as a repository, with individual packages for each
    blob or bunches of blobs that get installed together.
    Common prefix would be /lib/firmware, and the package would not need
    to carry it. As opposed to the Arch practice of installing 500MB
    of blobs together even though a typical user needs less than 1MB
    in most cases.

  * modules for python, and other languages with similar module structure.
    Common prefix would be /lib/python-3.8 or whatever, and it would be
    fine to use bare name of the module as the package name, without
    prefixing it with python- like say Arch does.

  * shared libraries for a particular libc/ld combo.
    Common prefix /lib/musl-x64, /lib/musl-arm, /lib/glibc-x64 without
    name clashes between them, and without ugly Arch-style lib32-
    prefixes. With minor effort, should allow installing shared library
    packages for non-native architectures and using them with qemu, and
    possibly handling Wine DLLs the same way (treating wine as an ld).

Package groups also provide a limited support for relocatable packages, but
that is more of an afterthough, and not a primary goal. Linux packages in
general must be assumed to be non-relocatable, and doing anything about that
is way beyond the scope of this project.


Package signing
~~~~~~~~~~~~~~~
Hashes and signatures are metadata and as such should be distributed
separately from the packages themselves.

# This should be obvious but I'm pretty sure there will be people asking why,
# in the year 2020+n, there is no support for attached signatures in a new
# package format, and complaining how grossly insecure mpkg therefore is.

While this is completely out of scope for mpkg, the idea is to employ multiple
independent signatures for reproducible packages, in which case attaching any
of those signatures to the package file itself doesn't even make sense.


Off-root deployment
~~~~~~~~~~~~~~~~~~~
That is, deploying packages under say /mnt instead of / without chroot.
In Arch, this is called `pacstrap`.

There was an idea to let mpkg do that, essentially by implementing a soft
chroot internally. However, it got scrapped. The only cases where it makes
sense, it can be done by chroot'ing to the target.

If a well-defined use case will pop up, there probably will be a dedicated
tool for doing that. At present however, the only viable initial installation
procedure with mpkg is to boot the target system and start deploying packages.
